home *** CD-ROM | disk | FTP | other *** search
/ PC Media 7 / PC MEDIA CD07.iso / share / prog / cm / cmtlist.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-06  |  9.1 KB  |  401 lines

  1. // CmTList.cc
  2. // -----------------------------------------------------------------
  3. // Compendium - C++ Container Class Library
  4. // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
  5. // -----------------------------------------------------------------
  6. // Singly linked list template implementation.
  7. // -----------------------------------------------------------------
  8.  
  9.  
  10. // "CmTLinkedList" is the list copy constructor.
  11. //
  12. template <class T> CmTLinkedList<T>::CmTLinkedList(const CmTLinkedList<T>& L)
  13.                                    : CmTContainer<T>(L)
  14. {
  15.   _first = _last = NULL;
  16.   copy(L);
  17. }
  18.  
  19.  
  20. // "~CmTLinkedList" is the list destructor.
  21. //
  22. template <class T> CmTLinkedList<T>::~CmTLinkedList()
  23. {
  24.   removeAll();
  25. }
  26.  
  27.  
  28. // "=" operator copies the contents of the input list into this list.
  29. //
  30. template <class T>
  31. CmTLinkedList<T>& CmTLinkedList<T>::operator=(const CmTLinkedList<T>& L)
  32. {
  33.   if (&L != this)
  34.   {
  35.     removeAll();
  36.     copy     (L);
  37.   }
  38.   return *this;
  39. }
  40.  
  41.  
  42. // "[]" indexing operator allows a list item to be accessed via an index.
  43. //
  44. template <class T> const T& CmTLinkedList<T>::operator[](int idx) const
  45. {
  46.   if (idx < 0 || idx >= _size) return _error;
  47.  
  48.   int         ii    = 0;
  49.   CmTLink<T> *rover = _first;
  50.   while (rover && ii < idx)
  51.   {
  52.     rover = rover->_next;
  53.     ii++;
  54.   }
  55.   return (rover) ? rover->_data : _error;
  56. }
  57.  
  58.  
  59. // "add" adds the specified item to the end of this list.
  60. //
  61. template <class T> Bool CmTLinkedList<T>::add(const T& rObj)
  62. {
  63.   return append(rObj);
  64. }
  65.  
  66.  
  67. // "append" adds the specified item to the end of this list.
  68. //
  69. template <class T> Bool CmTLinkedList<T>::append(const T& obj)
  70. {
  71.   CmTLink<T> *newlink = new CmTLink<T>(obj);
  72.   if (!newlink) return FALSE;
  73.  
  74.   if (!_first)
  75.     _first = _last = newlink;
  76.   else
  77.   {
  78.     _last->_next = newlink;
  79.     _last        = newlink;
  80.   }
  81.   _size++;
  82.   return TRUE;
  83. }
  84.  
  85.  
  86. // "prepend" adds the specified item to the beginning of this list.
  87. //
  88. template <class T> Bool CmTLinkedList<T>::prepend(const T& obj)
  89. {
  90.   CmTLink<T> *newlink = new CmTLink<T>(obj);
  91.   if (!newlink) return FALSE;
  92.  
  93.   if (!_first)
  94.     _first = _last = newlink;
  95.   else
  96.   {
  97.     newlink->_next = _first;
  98.     _first         = newlink;
  99.   }
  100.   _size++;
  101.   return TRUE;
  102. }
  103.  
  104.  
  105. // "insertAfter" searches for the first item equal to the specified
  106. // item in the list and inserts the second item immediately after.
  107. //
  108. template <class T>
  109. Bool CmTLinkedList<T>::insertAfter(const T& after, const T& rObj)
  110. {
  111.   if (!_first) return FALSE;
  112.  
  113.   CmTLink<T> *rover = _first;
  114.   Bool        found = FALSE;
  115.   while (rover && !found)
  116.   {
  117.     if (rover->_data == after) found = TRUE;
  118.     else                       rover = rover->_next;
  119.   }
  120.  
  121.   if (!found) return FALSE;
  122.  
  123.   CmTLink<T> *newlink = new CmTLink<T>(rObj);
  124.   if (!newlink) return FALSE;
  125.   newlink->_next = rover->_next;
  126.   rover->_next   = newlink;
  127.   if (rover == _last) _last = newlink;
  128.   _size++;
  129.   return TRUE;
  130. }
  131.  
  132.  
  133. // "insertBefore" searches for the first item equal to the specified
  134. // item in the list and inserts the second item immediately before.
  135. //
  136. template <class T>
  137. Bool CmTLinkedList<T>::insertBefore(const T& before, const T& rObj)
  138. {
  139.   if (!_first) return FALSE;
  140.  
  141.   CmTLink<T> *rover1 = _first;
  142.   CmTLink<T> *rover2 = _first;
  143.  
  144.   while (rover1 != NULL && rover1->_data != before)
  145.   {
  146.     rover2 = rover1;
  147.     rover1 = rover1->_next;
  148.   }
  149.  
  150.   if (rover1 == NULL) return FALSE;
  151.  
  152.   CmTLink<T> *newlink = new CmTLink<T>(rObj);
  153.   if (rover1 == rover2)
  154.   {
  155.     newlink->_next = _first;
  156.     _first         = newlink;
  157.   }
  158.   else
  159.   {
  160.     newlink->_next = rover2->_next;
  161.     rover2->_next  = newlink;
  162.   }
  163.   _size++;
  164.   return TRUE;
  165. }
  166.  
  167.  
  168. // "remove" removes the item equal to the specified item from the list.
  169. //
  170. template <class T> Bool CmTLinkedList<T>::remove(const T& rObj)
  171. {
  172.   if (!_first) return FALSE;                      // Empty list.
  173.  
  174.   if (_first->_data == rObj)                      // Item to remove is
  175.   {                                               // first in the list.
  176.     removeFirst();
  177.     return TRUE;
  178.   }
  179.  
  180.   if (_last->_data == rObj)                       // Item to remove is
  181.   {                                               // last in the list.
  182.     removeLast();
  183.     return TRUE;
  184.   }
  185.  
  186.   CmTLink<T> *rover1 = _first;                   // Search for item to
  187.   CmTLink<T> *rover2 = _first;                   // remove.
  188.  
  189.   while (rover1 != NULL && rover1->_data != rObj)
  190.   {
  191.     rover2 = rover1;
  192.     rover1 = rover1->_next;
  193.   }
  194.  
  195.   if (rover1 == NULL) return FALSE;               // Item was not found.
  196.   rover2->_next = rover2->_next->_next;           // Remove link from list.
  197.  
  198.   delete rover1;                                  // Delete the link.
  199.   _size--;
  200.   return TRUE;
  201. }
  202.  
  203.  
  204. // "removeFirst" removes and returns the first item in the list.
  205. //
  206. template <class T> T CmTLinkedList<T>::removeFirst()
  207. {
  208.   if (!_first) return _error;
  209.   T           ret  = _first->_data;
  210.   CmTLink<T> *temp = _first;
  211.   _first = _first->_next;
  212.   if (!_first) _last = NULL;
  213.   delete temp;
  214.   _size--;
  215.   return ret;
  216. }
  217.  
  218.  
  219. // "removeLast" removes and returns the last item in the list.
  220. //
  221. template <class T> T CmTLinkedList<T>::removeLast()
  222. {
  223.   if (!_last) return _error;
  224.   if (_last == _first)
  225.   {
  226.     T ret = _first->_data;
  227.     delete _first;
  228.     _first = _last = NULL;
  229.     _size  = 0;
  230.     return ret;
  231.   }
  232.  
  233.   CmTLink<T> *rover = _first;
  234.   while (rover->_next->_next)
  235.     rover = rover->_next;
  236.   T ret = rover->_next->_data;
  237.   delete rover->_next;
  238.   _last = rover;
  239.   _last->_next = NULL;
  240.   _size--;
  241.   return ret;
  242. }
  243.  
  244.  
  245. // "lookup" searches for the item equal to the specified item in the
  246. // list and returns the first occurrence.
  247. //
  248. template <class T> const T& CmTLinkedList<T>::lookup(const T& rObj) const
  249. {
  250.   CmTLink<T> *rover = _first;
  251.   Bool        found = FALSE;
  252.   while (rover && !found)
  253.   {
  254.     if (rover->_data == rObj) found = TRUE;
  255.     else                      rover = rover->_next;
  256.   }
  257.   return (found) ? rover->_data : _error;
  258. }
  259.  
  260.  
  261. // "first" returns a pointer to the first object in the list.
  262. //
  263. template <class T> const T& CmTLinkedList<T>::first() const
  264. {
  265.   return (_first) ? _first->_data : _error;
  266. }
  267.  
  268.  
  269. // "last" returns a pointer to the last object in the list.
  270. //
  271. template <class T> const T& CmTLinkedList<T>::last() const
  272. {
  273.   return (_last ) ? _last->_data  : _error;
  274. }
  275.  
  276.  
  277. // "contains" checks to see if the item equal to the specified item
  278. // is contained in this list.
  279. //
  280. template <class T> Bool CmTLinkedList<T>::contains(const T& rObj) const
  281. {
  282.   CmTLink<T> *rover = _first;
  283.   Bool        found = FALSE;
  284.   while (rover && !found)
  285.   {
  286.     if (rover->_data == rObj) found = TRUE;
  287.     else                      rover = rover->_next;
  288.   }
  289.   return found;
  290. }
  291.  
  292.  
  293. // "occurrences" counts the number of occurrences of the specified item.
  294. //
  295. template <class T> unsigned CmTLinkedList<T>::occurrences(const T& rObj) const
  296. {
  297.   CmTLink<T> *rover = _first;
  298.   unsigned    occur = 0;
  299.   while (rover)
  300.   {
  301.     if (rover->_data == rObj) occur++;
  302.     rover = rover->_next;
  303.   }
  304.   return occur;
  305. }
  306.  
  307.  
  308. // "removeAll" clears the contents of this list.
  309. //
  310. template <class T> void CmTLinkedList<T>::removeAll()
  311. {
  312.   CmTLink<T> *temp, *rover = _first;
  313.   while (rover)
  314.   {
  315.     temp = rover->_next;
  316.     delete rover;
  317.     rover = temp;
  318.   }
  319.   _first = _last = NULL;
  320.   _size  = 0;
  321. }
  322.  
  323.  
  324. // "newIterator" creates and returns a new list iterator.
  325. //
  326. template <class T> CmTIterator<T>* CmTLinkedList<T>::newIterator() const
  327. {
  328.   return new CmTLinkedListIterator<T>(*this);
  329. }
  330.  
  331.  
  332. // "CmTLinkedListIterator" is the iterator constructor.
  333. //
  334. template <class T>
  335. CmTLinkedListIterator<T>::CmTLinkedListIterator(const CmTLinkedList<T>& L)
  336.                                       : _list(L), _link(L._first)
  337. {}
  338.  
  339.  
  340. // "done" returns TRUE if the iterator can advance no further.
  341. //
  342. template <class T> Bool CmTLinkedListIterator<T>::done() const
  343. {
  344.   return (!_link);
  345. }
  346.  
  347.  
  348. // "next" returns the current list item and increments the iterator to
  349. // the next item in the list.
  350. //
  351. template <class T> const T& CmTLinkedListIterator<T>::next()
  352. {
  353.   if (!_link) return _list._error;
  354.   CmTLink<T> *temp = _link;
  355.   _link = _link->_next;
  356.   return temp->_data;
  357. }
  358.  
  359.  
  360. // "previous" backs the iterator up one object and returns that object.
  361. //
  362. template <class T> const T& CmTLinkedListIterator<T>::previous()
  363. {
  364.   if (!_link) return _list._error;
  365.   CmTLink<T> *temp = _link;
  366.   if (_link == _list._first)
  367.     _link = NULL;
  368.   else
  369.   {
  370.     CmTLink<T> *rover = _list._first;
  371.     while (rover && rover->_next != _link)
  372.       rover = rover->_next;
  373.     _link = rover;
  374.   }
  375.   return temp->_data;
  376. }
  377.  
  378.  
  379. // "current" returns the current item in the list.
  380. //
  381. template <class T> const T& CmTLinkedListIterator<T>::current() const
  382. {
  383.   return (_link) ? _link->_data : _list._error;
  384. }
  385.  
  386.  
  387. // "first" moves the iterator to the first item.
  388. //
  389. template <class T> void CmTLinkedListIterator<T>::first()
  390. {
  391.   _link = _list._first;
  392. }
  393.  
  394.  
  395. // "last" moves the iterator to the last item.
  396. //
  397. template <class T> void CmTLinkedListIterator<T>::last()
  398. {
  399.   _link = _list._last;
  400. }
  401.